<template>
    <div class="pagestyle">
        <div class="mask_title">语音报警设置</div>
        <el-form ref="formRef" :model="state.formData" :rules="state.rules" label-position="left">
            <el-row :gutter="24">
                <el-col :span="8">
                    <el-row :gutter="24">
                        <el-col :span="24" style="margin-top: 10px;">
                            <el-form-item label="异常广播" prop="exceptionBroadcastStatus">
                                <el-switch v-model="state.formData.exceptionBroadcastStatus" />
                            </el-form-item>
                        </el-col>
                        <el-col :span="24">
                            <el-form-item label="广播端口号" prop="broadcastPort">
                                <el-input class="w100" v-model="state.formData.broadcastPort" placeholder="请输入">
                                </el-input>
                            </el-form-item>
                        </el-col>
                        <el-col :span="24">
                            <p class="mask_sub_title">
                                <svg-icon icon-class="biaotitubiao" /><span>同一条播报轮询次数</span></p>
                        </el-col>
                        <el-col :span="24">
                            <el-form-item label="" prop="rotationNumber">
                                <el-radio-group v-model="state.formData.rotationNumber">
                                    <el-radio class="w100" style="margin-bottom: 10px;" :label="1" :value="1"
                                        size="small">播一次
                                    </el-radio>
                                    <el-radio class="w100" style="margin-bottom: 10px;" :label="2" :value="2"
                                        size="small">播
                                        <el-input style="width: 100px;margin: 0 5px;" v-model="state.oneRadio"
                                            placeholder="请输入">
                                        </el-input>次</el-radio>
                                    <el-radio class="w100" style="margin-bottom: 10px;" :label="3" :value="3"
                                        size="small">持续播报
                                    </el-radio>
                                    <el-radio class="w100" style="margin-bottom: 10px;" :label="4" :value="4"
                                        size="small">确认后不播报
                                    </el-radio>
                                    <el-radio class="w100" style="margin-bottom: 10px;" :label="5" :value="5"
                                        size="small">确认后未解除，每隔
                                        <el-input style="width: 100px;margin: 0 5px;" v-model="state.twoRadio"
                                            placeholder="请输入">
                                        </el-input>分钟播报</el-radio>
                                </el-radio-group>
                            </el-form-item>
                        </el-col>
                        <el-col :span="24">
                            <el-form-item label="地面声光报警所在交换IP" prop="groupAlarmIp">
                                <!-- <el-select class="w100" clearable filterable v-model="state.formData.groupAlarmIp"
                                    placeholder="请选择">
                                    <el-option v-for="item in state.stationInNumList" :key="item" :label="item"
                                        :value="item">
                                    </el-option>
                                </el-select> -->
                                <el-input v-model="state.formData.groupAlarmIp" placeholder="请输入">
                                </el-input>
                            </el-form-item>
                        </el-col>
                        <el-col :span="24">
                            <el-form-item label="语音报警类型" prop="voiceAlarmType">
                                <el-select class="w100" clearable filterable v-model="state.formData.voiceAlarmType"
                                    placeholder="请选择">
                                    <el-option v-for="item in state.voicealarmList" :key="item" :label="item"
                                        :value="item">
                                    </el-option>
                                </el-select>
                            </el-form-item>
                        </el-col>
                        <el-col :span="22">
                            <el-form-item label="语音包" prop="voicePack">
                                <el-select class="w100" clearable filterable v-model="state.formData.voicePack"
                                    placeholder="请选择">
                                    <el-option v-for="item in state.stationInNumList" :key="item" :label="item"
                                        :value="item">
                                    </el-option>
                                </el-select>
                            </el-form-item>
                        </el-col>
                        <el-col :span="2">
                            <el-button type="text" @click="moreClick">更多</el-button>
                        </el-col>
                    </el-row>
                </el-col>
                <el-col :span="24">
                    <p class="mask_sub_title">
                        <svg-icon  icon-class="biaotitubiao" /><span>语音报警类型与优先级</span></p>
                </el-col>
                <el-col :span="11">
                    <vxe-table height="200" :data="state.voiceAlarmDtoListLeft" border="inner"
                        @checkbox-change="checkchange">
                        <vxe-column type="checkbox" :width="42"></vxe-column>
                        <vxe-column field="type" title="报警类型"></vxe-column>
                        <vxe-column title="操作" :width="80">
                            <template #default="{ row }">
                                <el-button v-if="row.name !=null" type="text" @click="selectClick(row)">配置</el-button>
                            </template>
                        </vxe-column>
                    </vxe-table>
                </el-col>
                <el-col :span="2" style="display: flex;flex-direction: column;align-items: center;position: relative;">
                    <div style="text-align: center;position: absolute;top: 50%;transform: translateY(-50%);
                    display: flex;
    flex-direction: column;">
                        <el-button type="primary" @click="letfClick">
                            <svg-icon icon-class="you" />
                        </el-button>
                        <el-button type="danger" style="margin: 10px 0 0 -2px;" @click="rightClick">
                            <svg-icon style="transform: rotate(-180deg)" 
                                icon-class="zuo" />
                        </el-button>
                    </div>
                </el-col>
                <el-col :span="11">
                    <vxe-table height="200" :data="state.formData.voiceAlarmDtoList" :row-config="{useKey: true}"
                        border="inner" ref="xTable" @checkbox-change="checkchangeRight" :key="indexl">
                        <vxe-column type="checkbox" :width="42"></vxe-column>
                        <vxe-column field="type" title="报警类型"></vxe-column>
                        <vxe-column title="操作" :width="120">
                            <template #default="{ row }">
                                <el-button v-if="row.name !=null" type="text" @click="selectClick(row)">配置</el-button>
                                <el-button type="text" @click="topClick(row)">
                                    <svg-icon  icon-class="shang" />
                                </el-button>
                                <el-button type="text">
                                    <svg-icon class="drag-btn" icon-class="tuodongpaixu" />
                                </el-button>
                            </template>
                        </vxe-column>
                    </vxe-table>
                </el-col>
                <el-col :span="24" style="text-align: right;margin-top: 20px">
                    <el-button type="primary" @click="addClick">确定</el-button>
                </el-col>
            </el-row>
        </el-form>
        <!-- 语音调试器 -->
        <el-drawer v-model="state.drawerShow" direction="rtl" size="50%" close-on-click-modal :modal="true">
            <template #header="{ close, titleId, titleClass }">
                <h4 class="mask_sub_title">
                    <svg-icon  icon-class="biaotitubiao" /><span>系统语音库</span></h4>
            </template>
            <el-form ref="formRef" :model="state.formData" :rules="state.rules" label-position="top">
                <el-row :gutter="24">
                    <el-col :span="8">
                        <el-row :gutter="24">
                            <el-col :span="10">
                                <el-form-item label="多音字">
                                    <el-input v-model="state.formData.pointValue" placeholder="请输入">
                                    </el-input>
                                </el-form-item>
                            </el-col>
                            <el-col :span="1">
                                <el-form-item label="">
                                    <span style="margin-top: 30px;">=</span>
                                </el-form-item>
                            </el-col>
                            <el-col :span="10">
                                <el-form-item label="替换字">
                                    <el-input v-model="state.formData.pointValue" placeholder="请输入">
                                    </el-input>
                                </el-form-item>
                            </el-col>
                            <el-col :span="24">
                                <el-button class="w100" type="primary">插入</el-button>
                            </el-col>
                            <el-col :span="24" style="margin-top: 10px;">
                                <el-form-item label="已有字库">
                                    <div class="yiyou">
                                        <div :class="item==state.activeItem?'active':''"
                                            @mouseenter="handleMouseEnter(item)" @mouseleave="handleMouseLeave"
                                            v-for="item in 10">
                                            <span>0=零</span><span v-if="item==state.activeItem"
                                                class="del hover">删除</span></div>
                                    </div>
                                </el-form-item>
                            </el-col>
                        </el-row>
                    </el-col>
                    <el-col :span="16">
                        <el-row :gutter="24">
                            <el-col :span="20">
                                <el-form-item label="语音库">
                                    <el-select class="w100" clearable filterable
                                        v-model="state.formData.comparationType" placeholder="请选择">
                                        <el-option v-for="item in state.stationInNumList" :key="item" :label="item"
                                            :value="item">
                                        </el-option>
                                    </el-select>
                                </el-form-item>
                            </el-col>
                            <el-col :span="3">
                                <el-form-item label="">
                                    <el-button type="text" style="margin-top: 30px;">
                                        <svg-icon style="width: 40px;height: 40px" 
                                            icon-class="bofang" />试听</el-button>
                                </el-form-item>
                            </el-col>
                            <el-col :span="24">
                                <el-form-item label="试听内容">
                                    <el-input v-model="state.formData.pointValue" placeholder="请输入">
                                    </el-input>
                                </el-form-item>
                            </el-col>
                            <el-col :span="24">
                                <!-- 音频图 -->
                                <div style="display: flex;flex-direction: column">
                                    <canvas ref="recorder" id="canvas"></canvas>
                                    <audio v-show="false" ref="audioRef" src="/dayue.mp3" controls autoplay></audio>
                                    <div style="display: flex;justify-content: end;">
                                        <el-button type="text">默认语速</el-button>
                                    </div>
                                    <div style="color: rgba(171, 171, 171, 1);display: flex;align-items: center;">
                                        慢
                                        <el-slider @change="sliderChange" style="margin: 5px 20px 0;"
                                            v-model="state.formData.value1" size="9" />快
                                    </div>
                                </div>
                            </el-col>
                        </el-row>
                    </el-col>
                </el-row>
            </el-form>
        </el-drawer>
        <teleport to="body">
            <vxe-modal esc-closable destroy-on-close :lock-view="false" :width="500" :height="auto"
                v-model="state.addModal" resize :mask="true" showFooter>
                <template #title>
                    <div class="w100 h100 fsc mask_title">配置优先级</div>
                </template>
                <template #default>
                    <vxe-table ref="configTable" style="margin: 10px;" height="200" :data="state.childrenList"
                        border="inner">
                        <div v-if="state.nameType == 'A'">
                            <vxe-column field="level" title="优先级"></vxe-column>
                            <vxe-column field="type" title="测点类型"></vxe-column>
                            <vxe-column field="name" title="测点名称"></vxe-column>
                            <vxe-column title="操作" :width="120">
                                <template #default="{ row }">
                                    <el-button type="text">
                                        <svg-icon class="tuozhuai"  icon-class="tuodongpaixu" />
                                    </el-button>
                                </template>
                            </vxe-column>
                        </div>
                        <div v-if="state.nameType == 'B'">
                            <vxe-column field="level" title="优先级"></vxe-column>
                            <vxe-column field="name" title="分站名称"></vxe-column>
                            <vxe-column title="操作" :width="120">
                                <template #default="{ row }">
                                    <el-button type="text">
                                        <svg-icon  icon-class="tuodongpaixu" />
                                    </el-button>
                                </template>
                            </vxe-column>
                        </div>
                        <div v-if="state.nameType == 'C'">
                            <vxe-column field="level" title="优先级"></vxe-column>
                            <vxe-column field="type" title="设备类型"></vxe-column>
                            <vxe-column field="name" title="设备名称"></vxe-column>
                            <vxe-column title="操作" :width="120">
                                <template #default="{ row }">
                                    <el-button type="text">
                                        <svg-icon  icon-class="tuodongpaixu" />
                                    </el-button>
                                </template>
                            </vxe-column>
                        </div>
                        <div v-if="state.nameType == 'D'">
                            <vxe-column field="level" title="优先级"></vxe-column>
                            <vxe-column field="name" title="名称"></vxe-column>
                            <vxe-column title="操作" :width="120">
                                <template #default="{ row }">
                                    <el-button type="text">
                                        <svg-icon  icon-class="tuodongpaixu" />
                                    </el-button>
                                </template>
                            </vxe-column>
                        </div>
                    </vxe-table>
                </template>
                <template #footer>
                    <el-button type="info" @click="configCancel">取消</el-button>
                    <el-button type="primary" @click="configClick">确定</el-button>
                    </template>
            </vxe-modal>
        </teleport>
    </div>
</template>
<script setup>
    import {
        nextTick
    } from 'vue';
    import {
        ElMessage,
        ElMessageBox
    } from 'element-plus'
    import Sortable from 'sortablejs'
    import {
        getvoicelistAlarmTypes,
        getvoicevoiceAlarmTypes
    } from '@/api/config'
    import axios from "@/utils/request"
    const recorder = ref(null)
    const rotationNumber = ref(1)
    const audioRef = ref(null)
    const xTable = ref(null)
    let sortable1 = null
    let  initTime = null
    const configTable = ref(null)
    let sortableconfig = null
    const indexl = ref(0)
    let state = reactive({
        voiceAlarmDtoListLeft: [],
        drawerShow: false,
        formData: {
            exceptionBroadcastStatus: false
        },
        rules: {},
        activeItem: undefined,
        voicealarmList: [],
        selectLeftList: [],
        selectRightList: [],
        addModal: false,
        childrenList: [],
        oneRadio: undefined,
        twoRadio: undefined,
        voiceAlarmDtoList: [],
        nameType: undefined,
        configObj: {},
        editId: undefined
    })

    function handleMouseEnter(item) {
        state.activeItem = item
    }

    function handleMouseLeave(item) {

    }

    function moreClick() {
        state.drawerShow = true
        nextTick(() => {
            const audio = audioRef.value
            const canvas = recorder.value
            const ctx = canvas.getContext("2d");

            function generateGradient(baseColor, count) {
                let hsl = baseColor.match(
                    /hsla?\((\d+),\s*(\d+%),\s*(\d+%),\s*([\d.]+)\)/
                );
                let h = parseInt(hsl[1], 10); // Hue
                let s = parseInt(hsl[2], 10); // Saturation
                let l = parseInt(hsl[3], 10); // Lightness
                let stepH = 360 / count;
                let stepL = 100 / (count + 1);
                let gradientColors = [];
                for (let i = 0; i < count; i++) {
                    gradientColors.push(`hsl(${h + i * stepH}, ${s}%, ${l}%)`);
                }
                return gradientColors;
            }

            // 使用示例
            let baseColor = "hsla(212, 100%, 80%, 1)"; // 蓝色
            let gradient = generateGradient(baseColor, 90); // 200种颜色
            // 初始化画布
            canvas.width = window.innerWidth;
            canvas.height = 200;

            // 绑定播放事件
            let isInit = false;
            let analyser, data;
            audio.onplay = () => {
                if (isInit) return;
                // 创建音频上下文
                const audioCtx = new AudioContext();
                // 创建音频源
                const source = audioCtx.createMediaElementSource(audio);
                // 创建分析器节点
                analyser = audioCtx.createAnalyser();
                // 设置窗口大小，窗口越大，分析结果越细腻
                analyser.fftSize = 512;
                data = new Uint8Array(analyser.frequencyBinCount);
                // 将源连接到分析器节点
                source.connect(analyser);
                // 将分析器节点连接到输出设备
                analyser.connect(audioCtx.destination);
                isInit = true;
            };

            function drawRoundedRect(x, y, width, height, radius) {
                if (height === 0) return;
                ctx.beginPath();
                ctx.moveTo(x + radius, y);
                ctx.lineTo(x + width - radius, y);
                ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
                ctx.lineTo(x + width, y + height - radius);
                ctx.quadraticCurveTo(
                    x + width,
                    y + height,
                    x + width - radius,
                    y + height
                );
                ctx.lineTo(x + radius, y + height);
                ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
                ctx.lineTo(x, y + radius);
                ctx.quadraticCurveTo(x, y, x + radius, y);
                ctx.fill();
            }

            // 绘制内容
            function draw() {
                requestAnimationFrame(draw);
                // 清空画布
                const {
                    width,
                    height
                } = canvas;
                ctx.clearRect(0, 0, width, height);
                if (!isInit) return;
                // 把分析器节点的数据更新到data中
                analyser.getByteFrequencyData(data);
                const len = data.length;
                const barWidth = width / len * 3 + 30;
                // 每一个方块的高度
                const blockHeight = 6;
                for (let index = 0; index < data.length; index++) {
                    const _data = data[index];
                    const barHeight = (_data / 255) * height;
                    const x = index * barWidth;
                    const y = height - barHeight;
                    const blockCount = Math.round(barHeight / 10);
                    for (let number = 0; number < blockCount; number++) {
                        ctx.fillStyle = gradient[number];
                        const y = height - blockHeight * number;
                        drawRoundedRect(x, y, barWidth - 1, blockHeight - 1, 1);
                    }
                }
            }
            draw();

        })
    }

    function sliderChange(e) {
        audioRef.value.playbackRate = e;
    }

    function getvoicelistAlarmTypesData() {
        getvoicelistAlarmTypes().then(res => {
            state.voiceAlarmDtoListLeft = res.data
        })
        getvoicevoiceAlarmTypes().then(res => {
            state.voicealarmList = res.data
        })
    }

    function checkchange(e) {
        state.selectLeftList = e.records
    }

    function checkchangeRight(e) {
        state.selectRightList = e.records
    }

    function selectClick(row) {
        state.addModal = true
        state.childrenList = row.children
        // A -- 所有模拟量弹框   B -- 分站弹框    C-- 所有分站+模拟量弹框   D -- 普通弹框
        state.nameType = row.name
        state.configObj = row
        nextTick(() => {
            rowDropconfig()
        })

    }

    function letfClick() {
        state.selectLeftList.forEach((item, index) => {
            item.level = index + 1
        })
        state.formData.voiceAlarmDtoList = state.selectLeftList
        let arrnew = state.selectLeftList.map(item => {
            return item.type
        })
        // 两个数组相减
        let nnn = state.voiceAlarmDtoListLeft.filter(item => {
            return !arrnew.includes(item.type);
        });
        state.voiceAlarmDtoListLeft = nnn
    }

    function rightClick() {
        state.formData.voiceAlarmDtoList = state.selectLeftList
        let arrnew = state.selectRightList.map(item => {
            return item.type
        })
        // 两个数组相减
        let nnn = state.formData.voiceAlarmDtoList.filter(item => {
            return !arrnew.includes(item.type);
        });
        state.formData.voiceAlarmDtoList = nnn
        state.voiceAlarmDtoListLeft = state.selectRightList.concat(state.voiceAlarmDtoListLeft)
    }

    function addClick() {
        let data = ''
        if (state.formData.rotationNumber == 2) {
            if (state.oneRadio) {
                data = ':' + state.oneRadio
            }
            state.formData.rotationNumber = state.formData.rotationNumber + data
        } else if (state.formData.rotationNumber == 2) {
            if (state.twoRadio) {
                data = ':' + state.twoRadio
            }
            state.formData.rotationNumber = state.formData.rotationNumber + data
        }
        if (state.editId) {
            axios.post('/voice/alarm/modify', state.formData).then(res => {
                if (res.code == 200) {
                    ElMessage.success(res.msg)
                    chaxunList()
                } else {
                    ElMessage.error(res.msg)
                }
            })
        } else {
            axios.post('/voice/alarm/add', state.formData).then(res => {
                if (res.code == 200) {
                    ElMessage.success(res.msg)
                } else {
                    ElMessage.error(res.msg)
                }
            })
        }
    }
    const rowDrop = () => {
        const $table = xTable.value
        sortable1 = Sortable.create($table.$el.querySelector('.body--wrapper>.vxe-table--body tbody'), {
            handle: '.drag-btn',
            onEnd: (sortableEvent) => {
                const newIndex = sortableEvent.newIndex
                const oldIndex = sortableEvent.oldIndex
                const currRow = state.formData.voiceAlarmDtoList.splice(oldIndex, 1)[0]
                state.formData.voiceAlarmDtoList.splice(newIndex, 0, currRow)
                state.formData.voiceAlarmDtoList.forEach((item, index) => {
                    if (item.type == currRow.type) {
                        item.level = newIndex + 1
                    } else {
                        item.level = index + 1
                    }
                })
            }
        })
    }
    const rowDropconfig = () => {
        const $table = configTable.value
        sortableconfig = Sortable.create($table.$el.querySelector(
            '.body--wrapper>.vxe-table--body tbody'), {
            handle: '.tuozhuai',
            onEnd: (sortableEvent) => {
                const newIndex = sortableEvent.newIndex
                const oldIndex = sortableEvent.oldIndex
                const currRow = state.childrenList.splice(oldIndex, 1)[0]
                state.childrenList.splice(newIndex, 0, currRow)
                state.childrenList.forEach((item, index) => {
                    if (item.name == currRow.name) {
                        item.level = newIndex + 1
                    } else {
                        item.level = index + 1
                    }
                })
            }
        })
    }

    function topClick(row) {
        indexl.value++
        let newarr = state.formData.voiceAlarmDtoList
        let obj = {}
        newarr.forEach((item, index) => {
            if (item.type == row.type) {
                obj = item
                newarr.splice(index, 1)[0]
            }
        })
        newarr.unshift(obj);
        nextTick(() => {
            state.formData.voiceAlarmDtoList = newarr
        })
    }

    function configCancel() {
        state.addModal = false
    }

    function configClick() {
        state.addModal = false
        state.voiceAlarmDtoListLeft.forEach(item => {
            if (item.type == state.configObj.type) {
                item.children = state.childrenList
            } else {
                item.children = state.configObj.children
            }
        })
        state.formData.voiceAlarmDtoList.forEach(item => {
            if (item.type == state.configObj.type) {
                item.children = state.childrenList
            } else {
                item.children = state.configObj.children
            }
        })

    }
    nextTick(() => {
        // 加载完成之后在绑定拖动事件
        initTime = setTimeout(() => {
            rowDrop()
        }, 500)
    })

    function chaxunList() {
        axios.post('/voice/alarm/getById', {
            id: 4
        }).then(res => {
            state.editId = res.data.id
            state.formData = res.data
            if (!Number(res.data.rotationNumber)) {
                let typearr = res.data.rotationNumber.split(':')
                if (typearr[0] == '2') {
                    state.formData.rotationNumber = Number(typearr[0])
                    state.oneRadio = typearr[1]
                } else if (typearr[0] == '4') {
                    state.formData.rotationNumber = Number(typearr[0])
                    state.twoRadio = typearr[1]
                }
            } else {
                state.formData.rotationNumber = Number(res.data.rotationNumber)
            }
        })
    }
    chaxunList()
    getvoicelistAlarmTypesData()
    onMounted(() => {

    })
    onUnmounted(() => {
        clearTimeout(initTime)
        if (sortable1) {
            sortable1.destroy()
        }
        if (sortableconfig) {
            sortableconfig.destroy()
        }
    })
</script>

<style lang="scss" scoped>
    .drag-btn {
        cursor: move;
    }

    #canvas {
        border-radius: 8px;
        background: rgba(255, 255, 255, 1);
        box-shadow: inset 0px 0px 26px rgba(0, 0, 0, 0.15);
        height: 200px;
    }

    .pagestyle {
        background-color: rgba(255, 255, 255, .8);
        margin: 10px;
        padding: 10px;
        border-radius: 8px;
        overflow-y: auto;
    }

    .yiyou {
        display: flex;
        flex-direction: column;
        width: 100%;
        background-color: rgba(240, 243, 245, 0.36);

        .del {
            color: rgba(245, 108, 108, 1);
        }

        &>div {
            display: flex;
            justify-content: space-between;
            width: 100%;
            padding: 0 10px;

            &.active {
                background-color: rgba(42, 130, 228, 0.11);
            }
        }
    }

    :deep(.el-slider__button-wrapper) {
        top: -10px;
    }

    :deep(.el-slider__button) {
        width: 60px;
        height: 28px;
        border-radius: 17px;
        background: rgba(64, 158, 255, 1);
        box-shadow: 0px 0px 18px rgba(22, 103, 184, 0.33);
        position: relative;

        &::before {
            position: absolute;
            content: url('/siline.svg');
            left: 12px;
            top: 62%;
            transform: translateY(-50%);
        }
    }

    :deep(.el-slider__runway) {
        height: 9px;
    }

    :deep(.el-slider__bar) {
        background-color: transparent;
    }
</style>